﻿using CoachingOrganizer.Logic.Models.Tools.MoodLevel;
using CoachingOrganizer.WinPhone.UITools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;

namespace CoachingOrganizer.WinPhone.ViewModels.Tools.MoodLevel
{
    public class MoodLevelViewModel : ToolViewModelBase
    {
        private readonly MoodLevelModel _model;
        private MoodDayCacheViewModel[] _days;
        private MoodDayCacheViewModel _selectedDay;

        public DateTimeOffset StartDate
        {
            get { return _model.StartDate; }
            set { _model.StartDate = value.Date; }
        }

        public DateTimeOffset FinishDate
        {
            get { return _model.FinishDate; }
            set { _model.FinishDate = value.Date; }
        }

        public TimeSpan Period
        {
            get { return _model.Period; }
            set { _model.Period = value; }
        }

        public MoodDayCacheViewModel SelectedDay
        {
            get { return _selectedDay; }
            set
            {
                if (_selectedDay != value)
                {
                    _selectedDay = value;
                    _model.SelectedDay = value.Model;
                    OnPropertyChanged(() => SelectedDay);
                }
            }
        }

        public MoodDayCacheViewModel[] Days
        {
            get { return _days; }
            set { _days = value; }
        }

        public IEnumerable<MoodValuesLineViewModel> ChartLines
        {
            get { return EnumerateChartLines(); }
        }

        public ICommand GoDetailsCommand
        {
            get { return GetCommand(() => GoDetailsCommand, () => UIHelper.GoToPage(this, typeof(CoachingOrganizer.WinPhone.Pages.Tools.MoodLevel.MoodLevelPage))); }
        }

        public MoodLevelViewModel(MoodLevelModel model)
            : base(model)
        {
            _model = model;
            model.SelectedDayChanged += Model_SelectedDayChanged;
            model.ValuesChanged+=Model_ValuesChanged;
            InitModel();
        }

        private async void InitModel()
        {
            using (CancellationTokenSource cancellation = new CancellationTokenSource())
                await _model.LoadMoodValuesAsync(cancellation.Token);
            RefreshDays();
        }

        private void RefreshDays()
        {
            MoodDayCacheModel[] dayModels = _model.Days;
            _days = dayModels == null ? null : dayModels.Select(m => new MoodDayCacheViewModel(m)).ToArray();
            OnPropertyChanged(() => Days);
        }

        private IEnumerable<MoodValuesLineViewModel> EnumerateChartLines()
        {
            if (_selectedDay == null)
                yield break;
            IEnumerable<MoodValueModel> values = _model.EnumerateDayValues(_selectedDay.Date);
            if (values == null)
                yield break;
            MoodValueModel[] valuesArray = values.ToArray();
            for (int i = 2; i > valuesArray.Length; i++)
                yield return new MoodValuesLineViewModel(valuesArray[i - 1], valuesArray[i]);
        }

        private void Model_SelectedDayChanged(object sender, EventArgs e)
        {
            if (_days != null)
                _selectedDay = _days.FirstOrDefault(d => d.Model == _model.SelectedDay);
            OnPropertyChanged(() => ChartLines);
        }

        private void Model_ValuesChanged(object sender, EventArgs e)
        {
            OnPropertyChanged(() => ChartLines);
        }
    }
}
